package com.tgra;

import java.util.ArrayList;
import java.util.Random;
import java.util.Stack;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;

public class Maze
{
	int mazeWidth;
	int mazeLength;
	public Cell[][] cells;
	boolean[][] visited;
	Texture tex;
	Texture tex2;
	
	public Maze(int width, int length, Texture tex, Texture tex2, Texture goal)
	{
		this.tex = goal;
		this.tex2 = tex2;
		mazeWidth = width;
		mazeLength = length;
		cells = new Cell[width+1][length+1];
		visited = new boolean[width][length];
		for(int i = 0; i < width+1; i++)
		{
			for(int j = 0; j < length+1; j++)
			{
				cells[i][j] = new Cell(true, true, tex, tex2);
			}
		}
		for(int i = 0; i < mazeWidth; i++)
		{
			for(int j = 0; j < mazeLength; j++)
			{
				visited[i][j] = false;
			}
		}
	}
	public boolean hasWestWall(int i, int j)
	{
		return cells[i][j].westWall;
	}
	public boolean hasSouthWall(int i, int j)
	{
		return cells[i][j].southWall;
	}
	
	public void draw()
	{
		for(int i = 0; i < mazeWidth+1; i++)
		{
			for(int j = 0; j < mazeLength+1; j++)
			{
				Gdx.gl11.glPushMatrix();
				Gdx.gl11.glTranslatef((float)i, 0.0f, (float)j);
				if(j == mazeLength && i == mazeWidth)
				{
					cells[i][j].draw(true, true);
				}
				else if(j == mazeLength)
				{
					cells[i][j].draw(true, false);
				}
				else if(i == mazeWidth)
				{
					cells[i][j].draw(false,true);
				}
				else
				{
					cells[i][j].draw(false, false);
				}
				Gdx.gl11.glPopMatrix();
				if(i == mazeWidth && j == mazeLength)
				{
					Cube goal = new Cube(tex, tex2);
					Gdx.gl11.glPushMatrix();
					Gdx.gl11.glTranslatef((float)i - 0.5f, 0.5f, (float)j - 0.5f);
					Gdx.gl11.glScalef(0.3f,0.3f,0.3f);
					goal.draw();
					Gdx.gl11.glPopMatrix();
				}
			}
		}
	}
	
	public void generate(int currentX, int currentZ)
	{		
		visited[currentX][currentZ] = true;
		Random random = new Random();
		
		int[] N = {currentX, currentZ+1}; // North neighbor cell
		int[] E = {currentX+1, currentZ}; // East neighbor cell
		int[] S = {currentX, currentZ-1}; // South neighbor cell
		int[] W = {currentX-1, currentZ}; // West neighbor cell
		ArrayList<int[]> list = new ArrayList<int[]>();
		if(N[0] >= 0 && N[0] < mazeWidth && N[1] >= 0 && N[1] < mazeLength)
		{
			list.add(N);
		}
		if(E[0] >= 0 && E[0] < mazeWidth && E[1] >= 0 && E[1] < mazeLength)
		{
			list.add(E);
		}
		if(S[0] >= 0 && S[0] < mazeWidth && S[1] >= 0 && S[1] < mazeLength)
		{
			list.add(S);
		}
		if(W[0] >= 0 && W[0] < mazeWidth && W[1] >= 0 && W[1] < mazeLength)
		{
			list.add(W);
		}
		
		Stack<int[]> stack = new Stack<int[]>();
		int size = list.size();
		
		for(int i = 0; i < size; i++)
		{
			int[] next = list.get(random.nextInt(list.size()));
			while(next == null)
			{
				next = list.get(random.nextInt(list.size()));
			}
			stack.push(next);
			list.remove(next);
		}
		
		while(!stack.empty())
		{
			int[] current = stack.pop();
			if(visited[current[0]][current[1]] == false)
			{
				if(current[0] == currentX+1) // East
				{
					cells[currentX+1][currentZ].westWall = false;
				}
				else if(current[0] == currentX-1) // West
				{
					cells[currentX][currentZ].westWall = false;
				}
				else if(current[1] == currentZ+1) // North
				{
					cells[currentX][currentZ+1].southWall = false;
				}
				else if(current[1] == currentZ-1) // South
				{
					cells[currentX][currentZ].southWall = false;
				}
				generate(current[0], current[1]);
			}
		}
	}
}
